package com.boss.core.util;

import com.boss.core.BossConstants;
import com.boss.core.BossResponse;
import hudson.model.Hudson;
import hudson.model.User;
import hudson.tasks.Mailer;
import net.sf.json.JSONObject;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;

import javax.servlet.ServletException;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Iterator;
import java.util.List;

/**
 * Base Utility class in BOSS
 * @author Momin Noor Khan
 */
public class BossBaseUtil {
    /**
     * Perform HTTP POST on the given URL.
     * To-Do: Needs a thorough analysis. A lot of scenarios need to be taken care of
     * and appropriate message should be generated for the exception (if any).
     */
    public static BossResponse postToURL(String jobURL) throws IOException, ServletException {
        int responseCode = 0;
        String exceptionMsg = "";
        String stackTraceElement = "";
        BossResponse bossResponse = new BossResponse();

        try {
            URL url = new URL(jobURL);
            HttpURLConnection hConnection = (HttpURLConnection) url.openConnection();
            HttpURLConnection.setFollowRedirects(true);
            hConnection.setDoOutput(true);
            hConnection.setRequestMethod("POST");

            String password = Hudson.getAuthentication().getCredentials().toString();
            String username = User.current().getId();
            String userpassword = username + ":" + password;
            String encodedAuthorization = new String(Base64.encodeBase64(userpassword.getBytes()));

            hConnection.setRequestProperty("Authorization", "Basic " + encodedAuthorization);

            PrintStream printStream = new PrintStream(hConnection.getOutputStream());
            printStream.print("param1=abcd&amp;param2=1234"); //random text. Does not make any difference to functionality.
            printStream.close();
            hConnection.connect();

            responseCode = hConnection.getResponseCode();
            exceptionMsg = hConnection.getResponseMessage();

            bossResponse.setResponseCode(responseCode);
            bossResponse.setExceptionMsg(exceptionMsg);

            InputStream errorStream = hConnection.getErrorStream();
            if (errorStream != null) {
                int dummy;
                String result = "abc";
                while ((dummy = errorStream.read()) != -1) {
                    result = result + Integer.toString(dummy);
                }
                errorStream.close();
                bossResponse.setStackTraceElement(result);
            }

            if (HttpURLConnection.HTTP_OK == hConnection.getResponseCode()) {
                InputStream inputStream = hConnection.getInputStream();
                inputStream.close();
                hConnection.disconnect();
            }
        } catch (Exception e) {
            responseCode = HttpURLConnection.HTTP_FORBIDDEN;
            bossResponse.setResponseCode(responseCode);
            stackTraceElement = e.getStackTrace().toString();
            bossResponse.setStackTraceElement(stackTraceElement);
            e.printStackTrace();
        }
        return bossResponse;
    }

    public static String getStartedBy() {
        String startedBy;
        if (User.current().getId() != null) {
            startedBy = User.current().getId();
        } else {
            startedBy = "BOSS";
        }
        return startedBy;
    }

    public static String getStartedByUserName() {
        String startedByUserName;
        if(User.current().getId() != null) {
            startedByUserName = User.current().getFullName();
        } else {
            startedByUserName = "BOSS";
        }
        return startedByUserName;
    }

    public static String getStartedByUserId() {
        String startedByUserId;
        if(User.current().getId() != null) {
            startedByUserId = User.current().getId();
        } else {
            startedByUserId = "BOSS";
        }
        return startedByUserId;
    }

    public static String getStartedByUserDisplayName() {
        String startedByUserDisplayName;
        if(User.current().getId() != null) {
            startedByUserDisplayName = User.current().getDisplayName();
        } else {
            startedByUserDisplayName = "BOSS";
        }
        return startedByUserDisplayName;
    }

    public static String getStartedByUserEmailAddress() {
        String userEmailAddress = "";
        User currentUser = User.current();
        if(currentUser.getId() != null && currentUser.getProperty(Mailer.UserProperty.class) != null) {
            userEmailAddress = currentUser.getProperty(Mailer.UserProperty.class).getAddress();
        }
        return userEmailAddress;
    }

    public static void removeNulls(List<?> list) {
        for (Iterator<?> itr = list.iterator(); itr.hasNext(); ) {
            if (itr.next() == null) {
                itr.remove();
            }
        }
    }

    public static boolean isBlankOrDummy(String value) {
        boolean result = false;
        if (StringUtils.isBlank(value) || value.equals(BossConstants.DUMMY_VALUE)) {
            result = true;
        }
        return result;
    }

    public static JSONObject getObjectFromJson(JSONObject parentJsonObject, String key) {
        JSONObject childJsonObject = null;
        if (parentJsonObject != null && parentJsonObject.has(key)) {
            childJsonObject = parentJsonObject.getJSONObject(key);
        }
        return childJsonObject;
    }

    public static String getStringValueFromJson(JSONObject jsonObject, String key) {
        String value = "";
        if (contains(jsonObject, key)) {
            value = jsonObject.getString(key);
        }
        return value;
    }

    public static String getStringValueFromJson(JSONObject jsonObject, String parentKey, String key) {
        String value = "";
        if (contains(jsonObject, parentKey)) {
            JSONObject jsonObject2 = jsonObject.getJSONObject(parentKey);
            value = jsonObject2.getString(key);
        }
        return value;
    }

    public static boolean getBooleanValueFromJson(JSONObject jsonObject, String key) {
        boolean value = false;
        if (contains(jsonObject, key)) {
            value = jsonObject.getBoolean(key);
        }
        return value;
    }

    public static boolean contains(JSONObject jsonObject, String key) {
        boolean value = false;
        if (jsonObject != null && jsonObject.has(key)) {
            value = true;
        }
        return value;
    }
}
